package com.du.method;

import com.du.config.MyArray;
import com.du.config.MysqlRule;
import com.du.entity.ColumnInfo;
import com.du.entity.ConvertParam;
import com.du.entity.MysqlInfo;
import com.du.entity.TempInfo;

import java.util.List;
import java.util.regex.Pattern;

/**
 * @Desc : 转换方法
 * @Author: shuangdu
 * @date : 2021/3/30
 */
public class MysqlConvertMarkdown extends MysqlConvert implements ConvertMethod {

    public String parse(MysqlInfo info) {
        List<ColumnInfo> columns = info.getColumns();
        MyArray<TempInfo> tempArr = new MyArray<>();
        for (int i = 0; i < getTemplate().length(); i++) {
            char c = getTemplate().charAt(i);
            TempInfo tempInfo = new TempInfo();
            if (c == '@' && isExpression(i + 1, tempInfo)) {
                i += tempInfo.getWord().length() - 1;
            } else {
                tempInfo.setWord((c + ""));
            }
            tempArr.add(tempInfo);
        }

        StringBuilder sb = new StringBuilder();
        TempInfo[] tempInfos = tempArr.getArray(TempInfo.class);
        // 添加标题
        addTitle(sb);
        for (ColumnInfo columnInfo : columns) {
            for (TempInfo tempInfo : tempInfos) {
//                if (tempInfo == null) continue;
                if (tempInfo.isExpression()) {
                    List<String> colList = tempInfo.getColList();
                    Class<? extends ColumnInfo> infoClass = columnInfo.getClass();
                    colList.forEach(i -> {
                        try {

                            String expressionVal = (String)infoClass.getMethod("get" + i.substring(0, 1).toUpperCase() + i.substring(1))
                                    .invoke(columnInfo);
                            sb.append(expressionVal == null ? "" : expressionVal).append(" ");
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    });

                } else {
                    sb.append(tempInfo.getWord());
                }
            }
            sb.append("\n");
        }

        return sb.toString();
    }

    /**
     * 表达式以@开头，后面跟数字和-
     * @param index
     * @return
     */
    private boolean isExpression(int index, TempInfo tempInfo) {
        boolean noMatch = true;
        int i = index;
        while (i < getTemplate().length() && noMatch){
            String s = getTemplate().charAt(i) + "";
            if (!Pattern.matches("[0-9\\-]", s)) {
                noMatch = false;
            } else {
                i ++;
            }
        }
        if (i == index) return false;

        String expression = "@" + getTemplate().substring(index, i);

        boolean containsKey = templateFieldMap.containsKey(expression);

        if (!containsKey) return false;

        tempInfo.setWord(expression);
        tempInfo.setExpression(true);
        tempInfo.setColList(templateFieldMap.get(expression));

        return true;
    }

    /**
     * markdown表格跟根据 | 分割
     * @param sb
     */
    private void addTitle(StringBuilder sb) {
        String template = getTemplate();
        StringBuilder title = new StringBuilder();
        StringBuilder layout = new StringBuilder();
        String splitWord = "|";
        if (template.contains(splitWord)) {
            String[] split = template.split("\\|");
            for (int i = 0; i < split.length - 1; i++) {
                String expressionTitle = MysqlRule.COL_MAP.get(split[i + 1].trim());
                title.append(splitWord).append(expressionTitle == null ? "" : expressionTitle);
                layout.append(splitWord).append(":--");
            }
            sb.append(title).append(splitWord).append("\n");
            sb.append(layout).append(splitWord).append("\n");
        }
    }

    /**
     * 将Navicat的table表DDL语句转为markdown格式
     * DDL格式为：

     CREATE TABLE `d` (
     `id` bigint(20) NOT NULL AUTO_INCREMENT,
     `s,tr` tinyint(4) NOT NULL DEFAULT '127' COMMENT 'aaa',
     PRIMARY KEY (`id`,`s,tr`) USING BTREE,
     KEY `i_str` (`s,tr`) USING HASH
     ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

     * 转为markdown：

     |字段名称|字段类型|字段能否为空|字段默认值|字段描述|主键 or 索引|
     |:--|:--|:--|:--|:--|:--|
     |id |bigint(20) |否 | | |主键   |
     |s,tr |tinyint(4) |否 |127 |aaa |主键  索引 |


     * 参数 DDL语句 & markdown格式文字
     * @return
     */
    @Override
    public String parse() {
        ConvertParam param = ConvertContext.holder.getParam();
        initialize(param.getSourceText(), param.getTemplateText());
        return parse(generateInfo());
    }
}
